//
// As mentioned at http://en.wikipedia.org/wiki/XMLHttpRequest
//
if( !window.XMLHttpRequest ) XMLHttpRequest = function()
{
  try{ return new ActiveXObject("Msxml2.XMLHTTP.6.0") }catch(e){}
  try{ return new ActiveXObject("Msxml2.XMLHTTP.3.0") }catch(e){}
  try{ return new ActiveXObject("Msxml2.XMLHTTP") }catch(e){}
  try{ return new ActiveXObject("Microsoft.XMLHTTP") }catch(e){}
  throw new Error("Could not find an XMLHttpRequest alternative.")
};

//
// Makes an AJAX request to a local server function w/ optional arguments
//
// functionName: the name of the server's AJAX function to call
// opt_argv: an Array of arguments for the AJAX function
//
function RequestGet(function_name, opt_argv) {

  if (!opt_argv)
    opt_argv = new Array();

  // Find if the last arg is a callback function; save it
  var callback = null;
  var len = opt_argv.length;
  if (len > 0 && typeof opt_argv[len-1] == 'function') {
    callback = opt_argv[len-1];
    opt_argv.length--;
  }
  var async = (callback != null);

  // Encode the arguments in to a URI
  var query = 'action=' + encodeURIComponent(function_name);
  for (var i = 0; i < opt_argv.length; i++) {
    var key = 'arg' + i;
    var val = JSON.stringify(opt_argv[i]);
    query += '&' + key + '=' + encodeURIComponent(val);
  }
  query += '&time=' + new Date().getTime(); // IE cache workaround

  // Create an XMLHttpRequest 'GET' request w/ an optional callback handler
  var req = new XMLHttpRequest();
  req.open('GET', '/rpc?' + query, async);

  if (async) {
    req.onreadystatechange = function() {
      if(req.readyState == 4 && req.status == 200) {
        var response = null;
        try {
          response = JSON.parse(req.responseText, ReviveDate);
        }
        catch (e) {
         response = req.responseText;
        }
        callback(response);
      }
    }
  }

  // Make the actual request
  req.send(null);
}

// this "reviver" will parse dates like "Date(09/09/2001)"
function ReviveDate(key, value) {
  var d;
  if (typeof value === 'string' &&
      value.slice(0, 5) === 'Date(' &&
      value.slice(-1) === ')') {
      d = new Date(value.slice(5, -1));
      if (d) {
          return d;
      }
  }
  return value;
}

function RequestPost(function_name, opt_argv) {
  try {
    if (!opt_argv)
      opt_argv = new Array();

    // Find if the last arg is a callback function; save it
    var callback = null;
    var len = opt_argv.length;
    if (len > 0 && typeof opt_argv[len-1] == 'function') {
      callback = opt_argv[len-1];
      opt_argv.length--;
    }
    var async = (callback != null);

    // Build an Array of parameters, w/ function_name being the first parameter
    var params = new Array(function_name);
    for (var i = 0; i < opt_argv.length; i++) {
      params.push(opt_argv[i]);
    }
    var body = JSON.stringify(params);

    // Create an XMLHttpRequest 'POST' request w/ an optional callback handler
    var req = new XMLHttpRequest();
    req.open('POST', '/rpc', async);

    req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    req.setRequestHeader("Content-length", body.length);
    req.setRequestHeader("Connection", "close");

    if (async) {
      req.onreadystatechange = function() {
        if(req.readyState == 4 && req.status == 200) {
          var response = null;
          try {
            response = JSON.parse(req.responseText, ReviveDate);
          }
          catch (e) {
           response = req.responseText;
          }
          callback(response);
        }
      }
    }

    // Make the actual request
    req.send(body);
  }
  catch (err) {
    alert(err);
  }
}

// Adds a stub function that will pass the arguments to the AJAX call
function InstallFunctionGet(obj, functionName) {
  obj[functionName] = function() { RequestGet(functionName, arguments); }
}

// Adds a stub function that will pass the arguments to the AJAX call
function InstallFunctionPost(obj, functionName) {
  obj[functionName] = function() { RequestPost(functionName, arguments); }
}

// Server object that will contain the callable methods
var server = {};

// Insert names of callable methods
InstallFunctionPost(server, 'DeleteTask');
InstallFunctionPost(server, 'AddEditAction');
InstallFunctionPost(server, 'MarkTaskComplete');
InstallFunctionPost(server, 'MarkTaskNotComplete');
InstallFunctionPost(server, 'EmailNextActions');
InstallFunctionPost(server, 'AddProject');
InstallFunctionPost(server, 'MarkProjectComplete');
InstallFunctionPost(server, 'MarkProjectNotComplete');
InstallFunctionPost(server, 'EditProjectDescription');
InstallFunctionPost(server, 'AddEditProjectTask');
InstallFunctionPost(server, 'DeleteProjectTasks');
InstallFunctionPost(server, 'DeleteProject');
InstallFunctionGet(server, 'GetActions');
InstallFunctionGet(server, 'GetAction');
